using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using ICSharpCode.TextEditor.Document;

namespace ICSharpCode.TextEditor.UserControls
{
	public class FindAndReplaceForm : Form
	{
		private readonly TextEditorSearcher _search;

		private TextEditorControl _editor;

		public bool LastSearchWasBackward = false;

		public bool LastSearchLoopedAround;

		private readonly Dictionary<TextEditorControl, HighlightGroup> _highlightGroups = new Dictionary<TextEditorControl, HighlightGroup>();

		private IContainer components = null;

		private Label label1;

		private Label lblReplaceWith;

		private TextBox txtReplaceWith;

		private Button btnFindNext;

		private Button btnReplace;

		private Button btnReplaceAll;

		private CheckBox chkMatchWholeWord;

		private CheckBox chkMatchCase;

		private Button btnHighlightAll;

		private Button btnCancel;

		private Button btnFindPrevious;

		private ComboBox txtLookFor;

		private TextEditorControl Editor
		{
			set
			{
				this._editor = value;
				this._search.Document = this._editor.Document;
				this.UpdateTitleBar();
			}
		}
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool ReplaceMode
		{
			get
			{
				return this.txtReplaceWith.Visible;
			}
			set
			{
				Button button = this.btnReplace;
				bool visible = (this.btnReplaceAll.Visible = value);
				button.Visible = visible;
				Label label = this.lblReplaceWith;
				visible = (this.txtReplaceWith.Visible = value);
				label.Visible = visible;
				this.btnHighlightAll.Visible = !value;
				base.AcceptButton = (value ? this.btnReplace : this.btnFindNext);
				this.UpdateTitleBar();
			}
		}

		public string LookFor => this.txtLookFor.Text;

		public FindAndReplaceForm()
		{
			this.InitializeComponent();
			this._search = new TextEditorSearcher();
		}

		private void UpdateTitleBar()
		{
			string text = (this.ReplaceMode ? "Find & replace" : "Find");
			if (this._editor != null && this._editor.FileName != null)
			{
				text = text + " - " + Path.GetFileName(this._editor.FileName);
			}
			if (this._search.HasScanRegion)
			{
				text += " (selection only)";
			}
			this.Text = text;
		}

		public void ShowFor(TextEditorControl editor, bool replaceMode)
		{
			this.Editor = editor;
			string text = "";
			this._search.ClearScanRegion();
			SelectionManager selectionManager = editor.ActiveTextAreaControl.SelectionManager;
			if (selectionManager.HasSomethingSelected && selectionManager.SelectionCollection.Count == 1)
			{
				ISelection selection = selectionManager.SelectionCollection[0];
				if (selection.StartPosition.Line == selection.EndPosition.Line)
				{
					text = selectionManager.SelectedText;
				}
				else
				{
					this._search.SetScanRegion(selection);
				}
			}
			else
			{
				Caret caret = editor.ActiveTextAreaControl.Caret;
				int num = TextUtilities.FindWordStart(editor.Document, caret.Offset);
				int num2 = TextUtilities.FindWordEnd(editor.Document, caret.Offset);
				text = editor.Document.GetText(num, num2 - num);
			}
			if (!string.IsNullOrWhiteSpace(text) && !this.txtLookFor.Items.Contains(text))
			{
				this.txtLookFor.Items.Add(text);
			}
			this.txtLookFor.Text = text;
			this.ReplaceMode = replaceMode;
			base.Owner = (Form)editor.TopLevelControl;
			base.Show();
			this.txtLookFor.SelectAll();
			this.txtLookFor.Focus();
		}

		private void btnFindPrevious_Click(object sender, EventArgs e)
		{
			this.FindNext(viaF3: false, searchBackward: true, "Text not found");
		}

		private void btnFindNext_Click(object sender, EventArgs e)
		{
			this.FindNext(viaF3: false, searchBackward: false, "Text not found");
		}

		public TextRange FindNext(bool viaF3, bool searchBackward, string messageIfNotFound)
		{
			if (string.IsNullOrEmpty(this.txtLookFor.Text))
			{
				MessageBox.Show("No string specified to look for!");
				return null;
			}
			this.LastSearchWasBackward = searchBackward;
			this._search.LookFor = this.txtLookFor.Text;
			this._search.MatchCase = this.chkMatchCase.Checked;
			this._search.MatchWholeWordOnly = this.chkMatchWholeWord.Checked;
			Caret caret = this._editor.ActiveTextAreaControl.Caret;
			if (viaF3 && this._search.HasScanRegion && !caret.Offset.IsInRange(this._search.BeginOffset, this._search.EndOffset))
			{
				this._search.ClearScanRegion();
				this.UpdateTitleBar();
			}
			int beginAtOffset = caret.Offset - (searchBackward ? 1 : 0);
			TextRange textRange = this._search.FindNext(beginAtOffset, searchBackward, out this.LastSearchLoopedAround);
			if (textRange != null)
			{
				this.SelectResult(textRange);
			}
			else if (messageIfNotFound != null)
			{
				MessageBox.Show(messageIfNotFound);
			}
			return textRange;
		}

		private void SelectResult(TextRange range)
		{
			TextLocation startPosition = this._editor.Document.OffsetToPosition(range.Offset);
			TextLocation endPosition = this._editor.Document.OffsetToPosition(range.Offset + range.Length);
			this._editor.ActiveTextAreaControl.SelectionManager.SetSelection(startPosition, endPosition);
			this._editor.ActiveTextAreaControl.ScrollTo(startPosition.Line, startPosition.Column);
			this._editor.ActiveTextAreaControl.Caret.Position = this._editor.Document.OffsetToPosition(range.Offset + range.Length);
		}

		private void btnHighlightAll_Click(object sender, EventArgs e)
		{
			if (!this._highlightGroups.ContainsKey(this._editor))
			{
				this._highlightGroups[this._editor] = new HighlightGroup(this._editor);
			}
			HighlightGroup highlightGroup = this._highlightGroups[this._editor];
			if (string.IsNullOrEmpty(this.LookFor))
			{
				highlightGroup.ClearMarkers();
				return;
			}
			this._search.LookFor = this.txtLookFor.Text;
			this._search.MatchCase = this.chkMatchCase.Checked;
			this._search.MatchWholeWordOnly = this.chkMatchWholeWord.Checked;
			int beginAtOffset = 0;
			int num = 0;
			while (true)
			{
				bool loopedAround;
				TextRange textRange = this._search.FindNext(beginAtOffset, searchBackward: false, out loopedAround);
				if (textRange == null || loopedAround)
				{
					break;
				}
				beginAtOffset = textRange.Offset + textRange.Length;
				num++;
				TextMarker marker = new TextMarker(textRange.Offset, textRange.Length, TextMarkerType.SolidBlock, Color.Yellow, Color.Black);
				highlightGroup.AddMarker(marker);
			}
			if (num == 0)
			{
				MessageBox.Show("Search text not found.");
			}
			else
			{
				base.Close();
			}
		}

		private void FindAndReplaceForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (e.CloseReason != CloseReason.FormOwnerClosing)
			{
				if (base.Owner != null)
				{
					base.Owner.Select();
				}
				e.Cancel = true;
				base.Hide();
				this._search.ClearScanRegion();
				this._editor.Refresh();
			}
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			base.Close();
		}

		private void btnReplace_Click(object sender, EventArgs e)
		{
			SelectionManager selectionManager = this._editor.ActiveTextAreaControl.SelectionManager;
			if (string.Equals(selectionManager.SelectedText, this.txtLookFor.Text, StringComparison.OrdinalIgnoreCase))
			{
				this.InsertText(this.txtReplaceWith.Text);
			}
			this.FindNext(viaF3: false, this.LastSearchWasBackward, "Text not found.");
		}

		private void btnReplaceAll_Click(object sender, EventArgs e)
		{
			int num = 0;
			this._editor.ActiveTextAreaControl.Caret.Position = this._editor.Document.OffsetToPosition(this._search.BeginOffset);
			this._editor.Document.UndoStack.StartUndoGroup();
			try
			{
				while (this.FindNext(viaF3: false, searchBackward: false, null) != null && !this.LastSearchLoopedAround)
				{
					num++;
					this.InsertText(this.txtReplaceWith.Text);
				}
			}
			finally
			{
				this._editor.Document.UndoStack.EndUndoGroup();
			}
			if (num == 0)
			{
				MessageBox.Show("No occurrances found.");
				return;
			}
			MessageBox.Show($"Replaced {num} occurrances.");
			base.Close();
		}

		private void InsertText(string text)
		{
			TextArea textArea = this._editor.ActiveTextAreaControl.TextArea;
			textArea.Document.UndoStack.StartUndoGroup();
			try
			{
				if (textArea.SelectionManager.HasSomethingSelected)
				{
					textArea.Caret.Position = textArea.SelectionManager.SelectionCollection[0].StartPosition;
					textArea.SelectionManager.RemoveSelectedText();
				}
				textArea.InsertString(text);
			}
			finally
			{
				textArea.Document.UndoStack.EndUndoGroup();
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && this.components != null)
			{
				this.components.Dispose();
			}
			base.Dispose(disposing);
		}

		private void InitializeComponent()
		{
			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ICSharpCode.TextEditor.UserControls.FindAndReplaceForm));
			this.label1 = new System.Windows.Forms.Label();
			this.lblReplaceWith = new System.Windows.Forms.Label();
			this.txtReplaceWith = new System.Windows.Forms.TextBox();
			this.btnFindNext = new System.Windows.Forms.Button();
			this.btnReplace = new System.Windows.Forms.Button();
			this.btnReplaceAll = new System.Windows.Forms.Button();
			this.chkMatchWholeWord = new System.Windows.Forms.CheckBox();
			this.chkMatchCase = new System.Windows.Forms.CheckBox();
			this.btnHighlightAll = new System.Windows.Forms.Button();
			this.btnCancel = new System.Windows.Forms.Button();
			this.btnFindPrevious = new System.Windows.Forms.Button();
			this.txtLookFor = new System.Windows.Forms.ComboBox();
			base.SuspendLayout();
			this.label1.AutoSize = true;
			this.label1.Location = new System.Drawing.Point(12, 8);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(77, 12);
			this.label1.TabIndex = 0;
			this.label1.Text = "查找内容(&N):";
			this.lblReplaceWith.AutoSize = true;
			this.lblReplaceWith.Location = new System.Drawing.Point(25, 27);
			this.lblReplaceWith.Name = "lblReplaceWith";
			this.lblReplaceWith.Size = new System.Drawing.Size(65, 12);
			this.lblReplaceWith.TabIndex = 2;
			this.lblReplaceWith.Text = "替换为(&P):";
			this.txtReplaceWith.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
			this.txtReplaceWith.Location = new System.Drawing.Point(90, 25);
			this.txtReplaceWith.Name = "txtReplaceWith";
			this.txtReplaceWith.Size = new System.Drawing.Size(232, 21);
			this.txtReplaceWith.TabIndex = 3;
			this.btnFindNext.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
			this.btnFindNext.Location = new System.Drawing.Point(247, 65);
			this.btnFindNext.Name = "btnFindNext";
			this.btnFindNext.Size = new System.Drawing.Size(84, 21);
			this.btnFindNext.TabIndex = 6;
			this.btnFindNext.Text = "查找下一个(&F)";
			this.btnFindNext.UseVisualStyleBackColor = true;
			this.btnFindNext.Click += new System.EventHandler(btnFindNext_Click);
			this.btnReplace.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
			this.btnReplace.Location = new System.Drawing.Point(66, 91);
			this.btnReplace.Name = "btnReplace";
			this.btnReplace.Size = new System.Drawing.Size(84, 21);
			this.btnReplace.TabIndex = 7;
			this.btnReplace.Text = "替换(&R)";
			this.btnReplace.UseVisualStyleBackColor = true;
			this.btnReplace.Click += new System.EventHandler(btnReplace_Click);
			this.btnReplaceAll.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
			this.btnReplaceAll.Location = new System.Drawing.Point(157, 91);
			this.btnReplaceAll.Name = "btnReplaceAll";
			this.btnReplaceAll.Size = new System.Drawing.Size(84, 21);
			this.btnReplaceAll.TabIndex = 9;
			this.btnReplaceAll.Text = "全部替换(&A)";
			this.btnReplaceAll.UseVisualStyleBackColor = true;
			this.btnReplaceAll.Click += new System.EventHandler(btnReplaceAll_Click);
			this.chkMatchWholeWord.AutoSize = true;
			this.chkMatchWholeWord.Location = new System.Drawing.Point(178, 47);
			this.chkMatchWholeWord.Name = "chkMatchWholeWord";
			this.chkMatchWholeWord.Size = new System.Drawing.Size(90, 16);
			this.chkMatchWholeWord.TabIndex = 5;
			this.chkMatchWholeWord.Text = "全字匹配(&W)";
			this.chkMatchWholeWord.UseVisualStyleBackColor = true;
			this.chkMatchCase.AutoSize = true;
			this.chkMatchCase.Location = new System.Drawing.Point(90, 47);
			this.chkMatchCase.Name = "chkMatchCase";
			this.chkMatchCase.Size = new System.Drawing.Size(102, 16);
			this.chkMatchCase.TabIndex = 4;
			this.chkMatchCase.Text = "大小写匹配(&C)";
			this.chkMatchCase.UseVisualStyleBackColor = true;
			this.btnHighlightAll.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
			this.btnHighlightAll.Location = new System.Drawing.Point(105, 91);
			this.btnHighlightAll.Name = "btnHighlightAll";
			this.btnHighlightAll.Size = new System.Drawing.Size(136, 21);
			this.btnHighlightAll.TabIndex = 8;
			this.btnHighlightAll.Text = "查找全部并高亮显示(&H)";
			this.btnHighlightAll.UseVisualStyleBackColor = true;
			this.btnHighlightAll.Visible = false;
			this.btnHighlightAll.Click += new System.EventHandler(btnHighlightAll_Click);
			this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
			this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this.btnCancel.Location = new System.Drawing.Point(247, 91);
			this.btnCancel.Name = "btnCancel";
			this.btnCancel.Size = new System.Drawing.Size(84, 21);
			this.btnCancel.TabIndex = 6;
			this.btnCancel.Text = "取消(&C)";
			this.btnCancel.UseVisualStyleBackColor = true;
			this.btnCancel.Click += new System.EventHandler(btnCancel_Click);
			this.btnFindPrevious.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
			this.btnFindPrevious.Location = new System.Drawing.Point(157, 65);
			this.btnFindPrevious.Name = "btnFindPrevious";
			this.btnFindPrevious.Size = new System.Drawing.Size(84, 21);
			this.btnFindPrevious.TabIndex = 6;
			this.btnFindPrevious.Text = "查找上一个(&P)";
			this.btnFindPrevious.UseVisualStyleBackColor = true;
			this.btnFindPrevious.Click += new System.EventHandler(btnFindPrevious_Click);
			this.txtLookFor.FormattingEnabled = true;
			this.txtLookFor.Location = new System.Drawing.Point(90, 4);
			this.txtLookFor.Name = "txtLookFor";
			this.txtLookFor.Size = new System.Drawing.Size(232, 20);
			this.txtLookFor.TabIndex = 10;
			base.AcceptButton = this.btnReplace;
			base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 12f);
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			base.CancelButton = this.btnCancel;
			base.ClientSize = new System.Drawing.Size(334, 124);
			base.Controls.Add(this.txtLookFor);
			base.Controls.Add(this.chkMatchCase);
			base.Controls.Add(this.chkMatchWholeWord);
			base.Controls.Add(this.btnReplaceAll);
			base.Controls.Add(this.btnReplace);
			base.Controls.Add(this.btnHighlightAll);
			base.Controls.Add(this.btnCancel);
			base.Controls.Add(this.btnFindPrevious);
			base.Controls.Add(this.btnFindNext);
			base.Controls.Add(this.txtReplaceWith);
			base.Controls.Add(this.lblReplaceWith);
			base.Controls.Add(this.label1);
			base.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
			base.Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon");
			base.MaximizeBox = false;
			base.MinimizeBox = false;
			base.Name = "FindAndReplaceForm";
			base.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "查找和替换";
			base.FormClosing += new System.Windows.Forms.FormClosingEventHandler(FindAndReplaceForm_FormClosing);
			base.ResumeLayout(false);
			base.PerformLayout();
		}
	}
}
